// *****************************************************************************
// Copyright (c) 2008 - 2017 Qualcomm Technologies International, Ltd.
// %%version
//
// *****************************************************************************

#ifndef MATH_MISC_INCLUDED
#define MATH_MISC_INCLUDED

#include "math_library.h"

//*****************************************************************************
// MODULE:
//    $M.math.misc.log_add
//
// DESCRIPTION:
//    Calculate table approximation for log(X+Y) from log(X) and log(Y)
//
// INPUTS:
//    - r0 = log(X) in Q8.16 (KAL_ARCH3) / Q8.24 (KAL_ARCH4)
//    - r1 = log(Y), or I0 = pointer to log(Y) vector
//              in Q8.16 (KAL_ARCH3) / Q8.24 (KAL_ARCH4)
//
// OUTPUTS:
//    - r0 = approx. log(X+Y) in Q8.16 (KAL_ARCH3) / Q8.24 (KAL_ARCH4)
//
// TRASHED REGISTERS:
//    r0, r1, r2
//
// CPU USAGE:
//    PM = 10 words, Cycles = 10, DM = 256 words
//
// NOTES:
//    In case of a given vector for consecutive log addtion:
//       - r0 = initial value
//       - I0 = vector
//       - r10 = vector length
//*****************************************************************************
.MODULE $M.math.misc.log_add;

   .CODESEGMENT MATH_MISC_LOG_ADD_PM;
   .DATASEGMENT MATH_MISC_LOG_ADD_DM;

   //  |--- Word in Q8.16 (KAL_ARCH3) / Q8.24 (KAL_ARCH4) ----|
   //  |-- 4 BITS --|---- TBL_INDX ----|--- SHIFT_OUT_BITS ---|
#if defined(AUDIO_SECOND_CORE) && !defined(INSTALL_DUAL_CORE_SUPPORT)
   .VAR/DM_P1_RW table[] =
#elif defined(USE_SHARE_MEM)
   .VAR/DM_P0_RW table[] =
#else
   .VAR/DM1 table[] =
#endif
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000015258789120, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000030517578240, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000045776367360, 8),
                    Qfmt_(0.000061035156480, 8),
                    Qfmt_(0.000061035156480, 8),
                    Qfmt_(0.000061035156480, 8),
                    Qfmt_(0.000061035156480, 8),
                    Qfmt_(0.000061035156480, 8),
                    Qfmt_(0.000076293945600, 8),
                    Qfmt_(0.000076293945600, 8),
                    Qfmt_(0.000076293945600, 8),
                    Qfmt_(0.000076293945600, 8),
                    Qfmt_(0.000091552734720, 8),
                    Qfmt_(0.000091552734720, 8),
                    Qfmt_(0.000091552734720, 8),
                    Qfmt_(0.000091552734720, 8),
                    Qfmt_(0.000106811523840, 8),
                    Qfmt_(0.000106811523840, 8),
                    Qfmt_(0.000106811523840, 8),
                    Qfmt_(0.000122070312960, 8),
                    Qfmt_(0.000122070312960, 8),
                    Qfmt_(0.000122070312960, 8),
                    Qfmt_(0.000137329102080, 8),
                    Qfmt_(0.000137329102080, 8),
                    Qfmt_(0.000152587891200, 8),
                    Qfmt_(0.000152587891200, 8),
                    Qfmt_(0.000167846680320, 8),
                    Qfmt_(0.000167846680320, 8),
                    Qfmt_(0.000183105468160, 8),
                    Qfmt_(0.000183105468160, 8),
                    Qfmt_(0.000198364257280, 8),
                    Qfmt_(0.000198364257280, 8),
                    Qfmt_(0.000213623046400, 8),
                    Qfmt_(0.000213623046400, 8),
                    Qfmt_(0.000228881835520, 8),
                    Qfmt_(0.000244140624640, 8),
                    Qfmt_(0.000259399413760, 8),
                    Qfmt_(0.000259399413760, 8),
                    Qfmt_(0.000274658202880, 8),
                    Qfmt_(0.000289916992000, 8),
                    Qfmt_(0.000305175781120, 8),
                    Qfmt_(0.000320434570240, 8),
                    Qfmt_(0.000335693359360, 8),
                    Qfmt_(0.000350952148480, 8),
                    Qfmt_(0.000366210937600, 8),
                    Qfmt_(0.000381469726720, 8),
                    Qfmt_(0.000396728515840, 8),
                    Qfmt_(0.000411987304960, 8),
                    Qfmt_(0.000427246094080, 8),
                    Qfmt_(0.000442504883200, 8),
                    Qfmt_(0.000473022461440, 8),
                    Qfmt_(0.000488281250560, 8),
                    Qfmt_(0.000518798827520, 8),
                    Qfmt_(0.000534057616640, 8),
                    Qfmt_(0.000564575194880, 8),
                    Qfmt_(0.000579833984000, 8),
                    Qfmt_(0.000610351562240, 8),
                    Qfmt_(0.000640869140480, 8),
                    Qfmt_(0.000671386718720, 8),
                    Qfmt_(0.000701904296960, 8),
                    Qfmt_(0.000732421875200, 8),
                    Qfmt_(0.000762939453440, 8),
                    Qfmt_(0.000793457031680, 8),
                    Qfmt_(0.000823974609920, 8),
                    Qfmt_(0.000869750976000, 8),
                    Qfmt_(0.000900268554240, 8),
                    Qfmt_(0.000946044921600, 8),
                    Qfmt_(0.000991821288960, 8),
                    Qfmt_(0.001037597656320, 8),
                    Qfmt_(0.001083374023680, 8),
                    Qfmt_(0.001129150391040, 8),
                    Qfmt_(0.001174926758400, 8),
                    Qfmt_(0.001235961913600, 8),
                    Qfmt_(0.001281738280960, 8),
                    Qfmt_(0.001342773437440, 8),
                    Qfmt_(0.001403808593920, 8),
                    Qfmt_(0.001464843750400, 8),
                    Qfmt_(0.001525878906880, 8),
                    Qfmt_(0.001602172851200, 8),
                    Qfmt_(0.001663208007680, 8),
                    Qfmt_(0.001739501953280, 8),
                    Qfmt_(0.001815795898880, 8),
                    Qfmt_(0.001892089843200, 8),
                    Qfmt_(0.001983642577920, 8),
                    Qfmt_(0.002075195312640, 8),
                    Qfmt_(0.002166748047360, 8),
                    Qfmt_(0.002258300780800, 8),
                    Qfmt_(0.002365112304640, 8),
                    Qfmt_(0.002471923828480, 8),
                    Qfmt_(0.002578735351040, 8),
                    Qfmt_(0.002685546874880, 8),
                    Qfmt_(0.002807617187840, 8),
                    Qfmt_(0.002929687499520, 8),
                    Qfmt_(0.003067016601600, 8),
                    Qfmt_(0.003204345703680, 8),
                    Qfmt_(0.003341674804480, 8),
                    Qfmt_(0.003494262695680, 8),
                    Qfmt_(0.003646850585600, 8),
                    Qfmt_(0.003799438476800, 8),
                    Qfmt_(0.003967285155840, 8),
                    Qfmt_(0.004150390625280, 8),
                    Qfmt_(0.004333496093440, 8),
                    Qfmt_(0.004516601562880, 8),
                    Qfmt_(0.004730224609280, 8),
                    Qfmt_(0.004928588866560, 8),
                    Qfmt_(0.005157470703360, 8),
                    Qfmt_(0.005386352538880, 8),
                    Qfmt_(0.005615234374400, 8),
                    Qfmt_(0.005859375000320, 8),
                    Qfmt_(0.006118774414080, 8),
                    Qfmt_(0.006393432616960, 8),
                    Qfmt_(0.006683349608960, 8),
                    Qfmt_(0.006973266600960, 8),
                    Qfmt_(0.007278442383360, 8),
                    Qfmt_(0.007598876953600, 8),
                    Qfmt_(0.007934570312960, 8),
                    Qfmt_(0.008285522461440, 8),
                    Qfmt_(0.008651733399040, 8),
                    Qfmt_(0.009033203124480, 8),
                    Qfmt_(0.009445190429440, 8),
                    Qfmt_(0.009857177734400, 8),
                    Qfmt_(0.010284423828480, 8),
                    Qfmt_(0.010742187499520, 8),
                    Qfmt_(0.011215209960960, 8),
                    Qfmt_(0.011718750000640, 8),
                    Qfmt_(0.012237548828160, 8),
                    Qfmt_(0.012771606444800, 8),
                    Qfmt_(0.013336181640960, 8),
                    Qfmt_(0.013916015624960, 8),
                    Qfmt_(0.014541625976320, 8),
                    Qfmt_(0.015182495116800, 8),
                    Qfmt_(0.015838623046400, 8),
                    Qfmt_(0.016540527343360, 8),
                    Qfmt_(0.017272949218560, 8),
                    Qfmt_(0.018035888672000, 8),
                    Qfmt_(0.018829345703680, 8),
                    Qfmt_(0.019653320312320, 8),
                    Qfmt_(0.020523071289600, 8),
                    Qfmt_(0.021423339843840, 8),
                    Qfmt_(0.022354125976320, 8),
                    Qfmt_(0.023345947265280, 8),
                    Qfmt_(0.024368286132480, 8),
                    Qfmt_(0.025436401367040, 8),
                    Qfmt_(0.026550292968960, 8),
                    Qfmt_(0.027725219726080, 8),
                    Qfmt_(0.028930664062720, 8),
                    Qfmt_(0.030197143554560, 8),
                    Qfmt_(0.031524658202880, 8),
                    Qfmt_(0.032897949218560, 8),
                    Qfmt_(0.034347534179840, 8),
                    Qfmt_(0.035842895507200, 8),
                    Qfmt_(0.037414550781440, 8),
                    Qfmt_(0.039047241210880, 8),
                    Qfmt_(0.040756225585920, 8),
                    Qfmt_(0.042526245117440, 8),
                    Qfmt_(0.044387817382400, 8),
                    Qfmt_(0.046325683594240, 8),
                    Qfmt_(0.048339843750400, 8),
                    Qfmt_(0.050445556640000, 8),
                    Qfmt_(0.052627563476480, 8),
                    Qfmt_(0.054916381835520, 8),
                    Qfmt_(0.057312011718400, 8),
                    Qfmt_(0.059783935546880, 8),
                    Qfmt_(0.062377929687040, 8),
                    Qfmt_(0.065078735351040, 8),
                    Qfmt_(0.067901611328000, 8),
                    Qfmt_(0.070831298827520, 8),
                    Qfmt_(0.073883056640000, 8),
                    Qfmt_(0.077072143554560, 8),
                    Qfmt_(0.080398559569920, 8),
                    Qfmt_(0.083847045898240, 8),
                    Qfmt_(0.087448120117760, 8),
                    Qfmt_(0.091201782227200, 8),
                    Qfmt_(0.095123291015680, 8),
                    Qfmt_(0.099182128906240, 8),
                    Qfmt_(0.103424072266240, 8),
                    Qfmt_(0.107833862305280, 8),
                    Qfmt_(0.112426757812480, 8),
                    Qfmt_(0.117202758789120, 8),
                    Qfmt_(0.122192382812160, 8),
                    Qfmt_(0.127365112304640, 8),
                    Qfmt_(0.132751464843520, 8),
                    Qfmt_(0.138351440430080, 8),
                    Qfmt_(0.144180297852160, 8),
                    Qfmt_(0.150253295898880, 8),
                    Qfmt_(0.156555175781120, 8),
                    Qfmt_(0.163101196289280, 8),
                    Qfmt_(0.169921875000320, 8),
                    Qfmt_(0.177001953125120, 8),
                    Qfmt_(0.184356689452800, 8),
                    Qfmt_(0.192001342773760, 8),
                    Qfmt_(0.199935913085440, 8),
                    Qfmt_(0.208175659179520, 8),
                    Qfmt_(0.216735839843840, 8),
                    Qfmt_(0.225616455078400, 8),
                    Qfmt_(0.234832763672320, 8),
                    Qfmt_(0.244400024413440, 8),
                    Qfmt_(0.254318237304320, 8),
                    Qfmt_(0.264602661132800, 8),
                    Qfmt_(0.275268554688000, 8),
                    Qfmt_(0.286315917968640, 8),
                    Qfmt_(0.297775268554240, 8),
                    Qfmt_(0.309631347655680, 8),
                    Qfmt_(0.321914672851200, 8),
                    Qfmt_(0.334640502929920, 8),
                    Qfmt_(0.347808837890560, 8),
                    Qfmt_(0.361419677734400, 8),
                    Qfmt_(0.375503540039680, 8),
                    Qfmt_(0.390075683594240, 8),
                    Qfmt_(0.405120849608960, 8),
                    Qfmt_(0.420684814453760, 8),
                    Qfmt_(0.436737060546560, 8),
                    Qfmt_(0.453338623046400, 8),
                    Qfmt_(0.470458984375040, 8),
                    Qfmt_(0.488113403320320, 8),
                    Qfmt_(0.506332397460480, 8),
                    Qfmt_(0.525115966796800, 8),
                    Qfmt_(0.544479370117120, 8),
                    Qfmt_(0.564422607421440, 8),
                    Qfmt_(0.584960937500160, 8),
                    Qfmt_(0.606094360352000, 8),
                    Qfmt_(0.627838134766080, 8),
                    Qfmt_(0.650207519531520, 8),
                    Qfmt_(0.673187255859200, 8),
                    Qfmt_(0.696807861328640, 8),
                    Qfmt_(0.721069335937280, 8),
                    Qfmt_(0.745986938476800, 8),
                    Qfmt_(0.771545410156800, 8),
                    Qfmt_(0.797760009765120, 8),
                    Qfmt_(0.824645996093440, 8),
                    Qfmt_(0.852188110351360, 8),
                    Qfmt_(0.880401611328000, 8),
                    Qfmt_(0.909286499023360, 8),
                    Qfmt_(0.938842773437440, 8),
                    Qfmt_(0.969085693359360, 8),
                    Qfmt_(1.000000000000000, 8);

   .CONST TBL_INDX          (8);
   .CONST SHIFT_OUT_BITS    (DAWTH - TBL_INDX - 4);

   // table_low = -(pow2(tbl_index) - 0.5) / pow2(4)

#if defined(AUDIO_SECOND_CORE) && !defined(INSTALL_DUAL_CORE_SUPPORT)
   .VAR/DM_P1_RW table_low =
#elif defined(USE_SHARE_MEM)
   .VAR/DM_P0_RW table_low =
#else
   .VAR/DM1 table_low = 
#endif
                Qfmt_(-255.5 / 16, 8);

$math.log_add.vector:
   do calc_log_add;
   r1 = M[I0,MK1];

$math.log_add:
   r2 = r1 - r0;
   if POS r2 = Null - r2;
   // r2 = negDiff
   r2 = r2 - M[&table_low];
   // shift r3 to get index into table
   r2 = r2 ASHIFT -(SHIFT_OUT_BITS);
   if NEG r2 = Null;

   Words2Addr(r2);      // KAL_ARCH 4 words to address conversion macro

   r2 = M[table + r2];
   Null = r1 - r0;
   if NEG r1 = r0;
   r0 = r1 + r2;
   // r0 = approx log(X+Y)
   calc_log_add:
   rts;

.ENDMODULE;


//*****************************************************************************
// MODULE:
//    $M.math.misc.pow2_exp_pow2_table
//
// DESCRIPTION:
//    Calculate approximation for y = pow2(x)*exp(1-pow2(x))
//
// INPUTS:
//    - r0 = x in Q8.16 (KAL_ARCH3) / Q8.24 (KAL_ARCH4)
//
// OUTPUTS:
//    - r1 = y = approx pow2(x) * exp(1-pow2(x))
//              in Q1.23 (KAL_ARCH3) / Q1.31 (KAL_ARCH4)
//
// TRASHED REGISTERS:
//    - r0
//
// CPU USAGE:
//    PM = 7 words, Cycles = 7, DM = 64 words
//
// NOTES:
//*****************************************************************************
.MODULE $M.math.misc.pow2_exp_pow2_table;

   .CODESEGMENT MATH_MISC_POW2_TABLE_PM;
   .DATASEGMENT MATH_MISC_POW2_TABLE_DM;

   //  |--- Word in Q1.23 (KAL_ARCH3) / Q1.31 (KAL_ARCH4) ----|
   //  |--- 6 BITS ---|--- TBL_INDX ---|--- SHIFT_OUT_BITS ---|

#if defined(AUDIO_SECOND_CORE) && !defined(INSTALL_DUAL_CORE_SUPPORT)
   .VAR/DM_P1_RW table[] =
#elif defined(USE_SHARE_MEM)
   .VAR/DM_P0_RW table[] =
#else
   .VAR/DM1 table[] =
#endif
                    1.00000000000000,
                    0.99904836944541,
                    0.99614312183914,
                    0.99121527477286,
                    0.98420573857939,
                    0.97506677987674,
                    0.96376348504198,
                    0.95027519685029,
                    0.93459689397673,
                    0.91674047974385,
                    0.89673594356447,
                    0.87463235615352,
                    0.85049865796203,
                    0.82442419962582,
                    0.79651899373483,
                    0.76691363912268,
                    0.73575888234288,
                    0.70322478619844,
                    0.66949948224260,
                    0.63478749312312,
                    0.59930762147391,
                    0.56329041464172,
                    0.52697522863558,
                    0.49060692994020,
                    0.45443228975196,
                    0.41869614115421,
                    0.38363738500988,
                    0.34948494407563,
                    0.31645377613363,
                    0.28474106487687,
                    0.25452271099572,
                    0.22595024462839,
                    0.19914827347146,
                    0.17421256807037,
                    0.15120886712175,
                    0.13017246140154,
                    0.11110858598261,
                    0.09399361794219,
                    0.07877704239160,
                    0.06538411531365,
                    0.05371911949530,
                    0.04366908197505,
                    0.03510779994080,
                    0.02790000865214,
                    0.02190552095586,
                    0.01698317389138,
                    0.01299443355199,
                    0.00980653378511,
                    0.00729505572444,
                    0.00534589116890,
                    0.00385657065372,
                    0.00273697374930,
                    0.00190947186964,
                    0.00130858031167,
                    0.00088021470014,
                    0.00058065664845,
                    0.00037533433582,
                    0.00023751676755,
                    0.00014700733511,
                    0.00008890497749,
                    0.00005248197834,
                    0.00003020830543,
                    0.00001693514742,
                    0.00000923614961,
                    0.00000489443713;
   .CONST TBL_INDX        6;
   .CONST SHIFT_OUT_BITS    DAWTH - 6 - TBL_INDX;
   //.CONST TBL_INDX        FLOOR(LOG2($ARRAY_LENGTH_MACRO(table)-1));

   // This is a function of table step size
   .CONST TABLE_LOW         (1 << SHIFT_OUT_BITS-1);

$math.pow2_exp_pow2_table:
   r1 = r0 + TABLE_LOW;
   if LT r1 = 0;
   // shift r1 to get index into table
   r1 = r1 ASHIFT -(SHIFT_OUT_BITS);

   Words2Addr(r1);      // KAL_ARCH 4 words to address conversion macro

   r0 = r1 - (length(table) - ADDR_PER_WORD);
   if GT r1 = r1 - r0;
   // r1 = approx pow2(x)*exp(1-pow2(x))
   r1 = M[table + r1];
   rts;

.ENDMODULE;


//*****************************************************************************
// MODULE:
//    $M.math.misc.exp_int_table
//
// DESCRIPTION:
//    Calculate approximation for y = exp(0.5*expint(x));
//
// INPUTS:
//    - r0 = x in Q13.11 (KAL_ARCH3) / Q13.19 (KAL_ARCH4)
//
// OUTPUTS:
//    - r0 = y in Q3.21 (KAL_ARCH3) / Q3.29 (KAL_ARCH4)
//
// TRASHED REGISTERS:
//    r0, r1
//
// CPU USAGE:
//    PM = 7 words, Cycles = 7, DM = 128
//
// NOTES:
//*****************************************************************************
.MODULE $M.math.misc.exp_int_table;

   .CODESEGMENT MATH_MISC_EXP_INT_TABLE_PM;
   .DATASEGMENT MATH_MISC_EXP_INT_TABLE_DM;

   //  |--- Word in Q3.21 (KAL_ARCH3) / Q3.29 (KAL_ARCH4) ----|
   //  |----- 10 BITS ------|--- TBL_INDX ---| SHIFT_OUT_BITS |

#if defined(AUDIO_SECOND_CORE) && !defined(INSTALL_DUAL_CORE_SUPPORT)
   .VAR/DM_P1_RW table[] =
#elif defined(USE_SHARE_MEM)
   .VAR/DM_P0_RW table[] =
#else
   .VAR/DM1 table[] =
#endif
                    Qfmt_(3.090877056121840, 3),
                    Qfmt_(2.251761436462400, 3),
                    Qfmt_(1.892526149749760, 3),
                    Qfmt_(1.685633182525640, 3),
                    Qfmt_(1.549311637878400, 3),
                    Qfmt_(1.452224254608160, 3),
                    Qfmt_(1.379475593566880, 3),
                    Qfmt_(1.322979927063000, 3),
                    Qfmt_(1.277926921844480, 3),
                    Qfmt_(1.241258144378680, 3),
                    Qfmt_(1.210927009582520, 3),
                    Qfmt_(1.185506820678720, 3),
                    Qfmt_(1.163969993591320, 3),
                    Qfmt_(1.145556926727280, 3),
                    Qfmt_(1.129693031311040, 3),
                    Qfmt_(1.115933895111080, 3),
                    Qfmt_(1.103931903839120, 3),
                    Qfmt_(1.093410015106200, 3),
                    Qfmt_(1.084144115448000, 3),
                    Qfmt_(1.075952529907240, 3),
                    Qfmt_(1.068685531616200, 3),
                    Qfmt_(1.062218189239520, 3),
                    Qfmt_(1.056446075439440, 3),
                    Qfmt_(1.051280975341800, 3),
                    Qfmt_(1.046648979187000, 3),
                    Qfmt_(1.042485713958760, 3),
                    Qfmt_(1.038736820220960, 3),
                    Qfmt_(1.035354614257800, 3),
                    Qfmt_(1.032298564910880, 3),
                    Qfmt_(1.029532909393320, 3),
                    Qfmt_(1.027026176452640, 3),
                    Qfmt_(1.024751186370840, 3),
                    Qfmt_(1.022684574127200, 3),
                    Qfmt_(1.020804882049560, 3),
                    Qfmt_(1.019093036651600, 3),
                    Qfmt_(1.017532825469960, 3),
                    Qfmt_(1.016109466552720, 3),
                    Qfmt_(1.014809608459480, 3),
                    Qfmt_(1.013621807098400, 3),
                    Qfmt_(1.012535095214840, 3),
                    Qfmt_(1.011540889740000, 3),
                    Qfmt_(1.010630130767840, 3),
                    Qfmt_(1.009795188903800, 3),
                    Qfmt_(1.009029865264880, 3),
                    Qfmt_(1.008327484130840, 3),
                    Qfmt_(1.007682323455800, 3),
                    Qfmt_(1.007089614868160, 3),
                    Qfmt_(1.006545066833480, 3),
                    Qfmt_(1.006044387817400, 3),
                    Qfmt_(1.005583763122560, 3),
                    Qfmt_(1.005159854888920, 3),
                    Qfmt_(1.004769325256360, 3),
                    Qfmt_(1.004409790039080, 3),
                    Qfmt_(1.004078388214120, 3),
                    Qfmt_(1.003772735595720, 3),
                    Qfmt_(1.003490924835200, 3),
                    Qfmt_(1.003231048584000, 3),
                    Qfmt_(1.002991199493400, 3),
                    Qfmt_(1.002769470214840, 3),
                    Qfmt_(1.002564907073960, 3),
                    Qfmt_(1.002376079559320, 3),
                    Qfmt_(1.002201557159440, 3),
                    Qfmt_(1.002040386199960, 3),
                    Qfmt_(1.001891136169440, 3),
                    Qfmt_(1.001753330230720, 3),
                    Qfmt_(1.001625537872320, 3),
                    Qfmt_(1.001507759094240, 3),
                    Qfmt_(1.001398563385000, 3),
                    Qfmt_(1.001297473907480, 3),
                    Qfmt_(1.001204013824480, 3),
                    Qfmt_(1.001117229461680, 3),
                    Qfmt_(1.001037120819080, 3),
                    Qfmt_(1.000962734222400, 3),
                    Qfmt_(1.000893592834480, 3),
                    Qfmt_(1.000829696655280, 3),
                    Qfmt_(1.000770568847640, 3),
                    Qfmt_(1.000715732574480, 3),
                    Qfmt_(1.000665187835680, 3),
                    Qfmt_(1.000617980957040, 3),
                    Qfmt_(1.000574111938480, 3),
                    Qfmt_(1.000533580780040, 3),
                    Qfmt_(1.000495910644520, 3),
                    Qfmt_(1.000460624694840, 3),
                    Qfmt_(1.000428199768080, 3),
                    Qfmt_(1.000398159027080, 3),
                    Qfmt_(1.000370502471920, 3),
                    Qfmt_(1.000344276428240, 3),
                    Qfmt_(1.000320434570320, 3),
                    Qfmt_(1.000298023223880, 3),
                    Qfmt_(1.000277042388920, 3),
                    Qfmt_(1.000257968902600, 3),
                    Qfmt_(1.000239849090560, 3),
                    Qfmt_(1.000223159790040, 3),
                    Qfmt_(1.000207424163800, 3),
                    Qfmt_(1.000193119049080, 3),
                    Qfmt_(1.000179767608640, 3),
                    Qfmt_(1.000167369842520, 3),
                    Qfmt_(1.000155925750720, 3),
                    Qfmt_(1.000144958496080, 3),
                    Qfmt_(1.000134944915760, 3),
                    Qfmt_(1.000125885009760, 3),
                    Qfmt_(1.000116825103760, 3),
                    Qfmt_(1.000109195709240, 3),
                    Qfmt_(1.000101566314680, 3),
                    Qfmt_(1.000094413757320, 3),
                    Qfmt_(1.000088214874280, 3),
                    Qfmt_(1.000082015991200, 3),
                    Qfmt_(1.000076293945320, 3),
                    Qfmt_(1.000071048736560, 3),
                    Qfmt_(1.000066280365000, 3),
                    Qfmt_(1.000061511993400, 3),
                    Qfmt_(1.000057697296160, 3),
                    Qfmt_(1.000053405761720, 3),
                    Qfmt_(1.000050067901600, 3),
                    Qfmt_(1.000046730041520, 3),
                    Qfmt_(1.000043392181400, 3),
                    Qfmt_(1.000040531158440, 3),
                    Qfmt_(1.000037670135480, 3),
                    Qfmt_(1.000035285949720, 3),
                    Qfmt_(1.000032901763920, 3),
                    Qfmt_(1.000030517578120, 3),
                    Qfmt_(1.000028610229480, 3),
                    Qfmt_(1.000026226043720, 3),
                    Qfmt_(1.000024795532240, 3),
                    Qfmt_(1.000022888183600, 3),
                    Qfmt_(1.000021457672120, 3),
                    Qfmt_(1.000020027160640, 3),
                    Qfmt_(1.000018596649160, 3);

   .CONST TBL_INDX        7;
   .CONST SHIFT_OUT_BITS    DAWTH - 10 - TBL_INDX;

   // This is a function of the table step size and input Q format
   .CONST TABLE_LOW         (1 << SHIFT_OUT_BITS-1);

$math.exp_int_table:
   r1 = r0 - TABLE_LOW;
   // shift r1 to get index into table
   r1 = r1 ASHIFT -(SHIFT_OUT_BITS);
   if NEG r1 = Null;

   Words2Addr(r1);      // KAL_ARCH 4 words to address conversion macro

   r0 = r1 - (LENGTH(table) - ADDR_PER_WORD);
   if GT r1 = r1 - r0;

   r0 = M[table + r1];  // exp_int_table
   rts;

.ENDMODULE;


//******************************************************************************
// MODULE:
//    $math.acos_table
//
// DESCRIPTION:
//    Calculate approximation for y = acos(x);
//
// INPUTS:
//    r0 = x in Q1.23 (KAL_ARCH3) / Q1.31 (KAL_ARCH4)
//
// OUTPUTS:
//    r1 = y in Q4.20 (KAL_ARCH3) / Q4.28 (KAL_ARCH4)
//
// TRASHED REGISTERS:
//    r3
//
// CPU USAGE:
//    PM = 10 words
//******************************************************************************
.MODULE $M.math.misc.acos;

   .CODESEGMENT MATH_MISC_ACOS_PM;
   .DATASEGMENT MATH_MISC_ACOS_DM;

   //  |--- Word in Q4.20 (KAL_ARCH3) / Q4.28 (KAL_ARCH4) ----|
   //  | S |--- TBL_INDX ---|-------- SHIFT_OUT_BITS ---------|

   .CONST TBL_INDX          5;
   .CONST SHIFT_OUT_BITS    (DAWTH - TBL_INDX - 1);

#if defined(AUDIO_SECOND_CORE) && !defined(INSTALL_DUAL_CORE_SUPPORT)
   .VAR/DM_P1_RW table_low = (1 << SHIFT_OUT_BITS-1);
   .VAR/DM_P1_RW PI_Q4_20 = Qfmt_(3.14159265359, 4);
   .VAR/DM_P1_RW table[] =
#elif defined(USE_SHARE_MEM)
   .VAR/DM_P0_RW table_low = (1 << SHIFT_OUT_BITS-1);
   .VAR/DM_P0_RW PI_Q4_20 = Qfmt_(3.14159265359, 4);
   .VAR/DM_P0_RW table[] =
#else
   .VAR/DM1 table_low = (1 << SHIFT_OUT_BITS-1);
   .VAR/DM1 PI_Q4_20 = Qfmt_(3.14159265359, 4);

   .VAR/DM1 table[] =
#endif
             Qfmt_(1.539540290832520, 4),
             Qfmt_(1.539540290832520, 4),
             Qfmt_(1.508255004882813, 4),
             Qfmt_(1.476907730102539, 4),
             Qfmt_(1.445467948913574, 4),
             Qfmt_(1.413903236389160, 4),
             Qfmt_(1.382179260253906, 4),
             Qfmt_(1.350262641906738, 4),
             Qfmt_(1.318115234375000, 4),
             Qfmt_(1.285699844360352, 4),
             Qfmt_(1.252972602844238, 4),
             Qfmt_(1.219888687133789, 4),
             Qfmt_(1.186399459838867, 4),
             Qfmt_(1.152449607849121, 4),
             Qfmt_(1.117979049682617, 4),
             Qfmt_(1.082921028137207, 4),
             Qfmt_(1.047197341918945, 4),
             Qfmt_(1.010720252990723, 4),
             Qfmt_(0.973389625549316, 4),
             Qfmt_(0.935084342956543, 4),
             Qfmt_(0.895664215087891, 4),
             Qfmt_(0.854957580566406, 4),
             Qfmt_(0.812754631042480, 4),
             Qfmt_(0.768793106079102, 4),
             Qfmt_(0.722733497619629, 4),
             Qfmt_(0.674130439758301, 4),
             Qfmt_(0.622367858886719, 4),
             Qfmt_(0.566563606262207, 4),
             Qfmt_(0.505359649658203, 4),
             Qfmt_(0.436468124389648, 4),
             Qfmt_(0.355421066284180, 4),
             Qfmt_(0.250655174255371, 4),
             Qfmt_(0.000000000000000, 4);

$math.acos_table:
   r1 = ABS r0;
   r1 = r1 - M[&table_low];
   // shift r1 to get index into table
   r1 = r1 ASHIFT (-SHIFT_OUT_BITS);

   Words2Addr(r1);      // KAL_ARCH 4 words to address conversion macro

   r1 = M[(table + MK1) + r1];
   // r1 = approx acos(t0) in Q4.20 (KAL_ARCH3) / Q4.28 (KAL_ARCH4)
   Null = r0;
   if POS rts;
   r1 = Null - r1;
   r1 = M[&PI_Q4_20] + r1;
   rts;

.ENDMODULE;


#endif // MATH_MISC_INCLUDED
